package com.investmenttechnologyservices.services;

import static com.google.common.base.Preconditions.checkNotNull;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.TransactionOptions;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.inject.Inject;
import com.investmenttechnologyservices.model.Firm;
import com.investmenttechnologyservices.model.UserITS;


public class LoginServiceImpl implements LoginService {
	
	private final UserService userService;
	private final DatastoreService ds;
	
	@Inject
	LoginServiceImpl(UserService userService, DatastoreService ds) {
		this.userService = userService;
		this.ds = ds;
	}
	
	public UserInfo getUserInfo(HttpServletRequest req, HttpServletResponse res) {
		User user = userService.getCurrentUser();
		String loginURL = null;
		String logoutURL = null;
		if (user == null) {
			loginURL = userService.createLoginURL("/");
		} else {
			logoutURL = userService.createLogoutURL("/");
			setupUser(user);
		}
		return new UserInfo(user, loginURL, logoutURL);
	}

	/**
	 *  build user and firm records. when the user logs in for the first time
	 *  
	 * @param user
	 */
	private void setupUser(User user) {
		Transaction tx = null;
		try {
			String userId = user.getUserId();
			Entity entity = null;
			try {
				entity = ds.get(KeyFactory.createKey("user", userId));

			} catch (EntityNotFoundException ex) {
				// user does not exist yet - create it
			}
			
			if (entity == null) {
				tx = ds.beginTransaction(TransactionOptions.Builder.withXG(true));
				Firm firm = new Firm("$userfirm$"+user.getUserId(), "User firm " + user.getEmail(), null, null);
				Entity firmEntity = firm.asEntity();
				ds.put(firmEntity);
				Key firmKey = firmEntity.getKey();
				UserITS userITS = new UserITS(user.getUserId(), user.getEmail(), firmKey);
				ds.put(userITS.asEntity());
				tx.commit();
			}
			
		} catch (Exception ex) {
			if (tx != null && tx.isActive())
				tx.rollback();
		}
	}
	public Key getFirmKeyForCurrentUser() {
		User user = userService.getCurrentUser();
		checkNotNull(user, "user is not logged in");
		
		setupUser(user);

		String userId = user.getUserId().toString();
		
		Key firmKey = null;
		
		Key key = KeyFactory.createKey("user", userId);
		try {
			UserITS userITS = new UserITS(ds.get(key));
			firmKey = userITS.getFirmKey();
		}
		catch (EntityNotFoundException ex) {
			System.err.println("Could not get firm key from user.");
		}
		return firmKey;
	}
	
}
